package implementations;

import interfaces.Vertex;



/**
 * @author Kai Bielenberg
 * @author Oliver Behnke
 *
 * @param <V>
 */
public class VertexImpl<V> extends AbstractVertex<V> {
	// Element bietet die Moeglichkeit dem Vertex Informationen/Faerbung zu geben, z.B. einen Namen.
	private final V element;
	private final String name;

	// Private Konstruktor und ValueOf Methode,zur Erzeugung eines Vertex
	private VertexImpl(String name, V element){
		this.element=element;
		this.name=name;
	}
	
	static <V> VertexImpl<V> valueOf(String name, V element){
		return new VertexImpl<V>(name, element);
	}
	
	@Override
	public V element() {
		recordAccess();
		return element;
	}
	
	public String name() {
		recordAccess();
		return name;
	}
	
	@Override
	public String toString(){
		recordAccess();
		return this.name;
	}


	@Override
	public boolean equals(Object o) {
//      recordAccess wird im Getter aufgerufen.
//		recordAccess();
		//Quick Check for same Object
		if (o == this) return true;
		//Type Check
		if (!(o instanceof Vertex<?>)) return false;
		//Check of the Arguments
		return this.name.equals(((Vertex<?>) o).name()) && this.element.equals(((Vertex<?>) o).element()) ;
	}

// Funktioniert nicht, wenn V z.B. ein Integer und eine gleiche Wertung (=Integer-Wert) erhalten hat.
	@Override
	public int hashCode() {
		// Record Access wieder in den gettern
		
			double code = name.hashCode();
			double code2 = element.hashCode();
			long longBits = Double.doubleToLongBits(code + code2);
			return (int) (longBits ^ (longBits >>> 32));
			}
	
		

}
